#include "stm32f2xx.h"
#include "can_driver.h"
void can_gpio_config(CAN_TypeDef* can)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
	if(can == CAN1)
	{	
		RCC_AHB1PeriphClockCmd(CAN1_GPIO_CLK, ENABLE);
		GPIO_PinAFConfig(CAN1_GPIO_PORT, CAN1_RX_SOURCE, CAN1_AF_PORT);
		GPIO_PinAFConfig(CAN1_GPIO_PORT, CAN1_TX_SOURCE, CAN1_AF_PORT); 
		GPIO_InitStructure.GPIO_Pin = CAN1_RX_PIN|CAN1_TX_PIN ;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
		GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
		GPIO_Init(CAN1_GPIO_PORT, &GPIO_InitStructure);
	}

	if(can == CAN2)
	{
		RCC_AHB1PeriphClockCmd(CAN2_GPIO_CLK, ENABLE);
		GPIO_PinAFConfig(CAN2_GPIO_PORT, CAN2_RX_SOURCE, CAN2_AF_PORT);
		GPIO_PinAFConfig(CAN2_GPIO_PORT, CAN2_TX_SOURCE, CAN2_AF_PORT); 
		GPIO_InitStructure.GPIO_Pin = CAN2_RX_PIN|CAN2_TX_PIN ;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
		GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
		GPIO_Init(CAN2_GPIO_PORT, &GPIO_InitStructure);
	}
}

void can_baudrate_set(CAN_TypeDef* can, uint32_t baudrate)
{
	CAN_InitTypeDef CAN_InitStructure;
	CAN_DeInit(can);
    
     if(can == CAN1)
    {
        RCC_APB1PeriphClockCmd(CAN1_CLK, ENABLE);
    }
    else if(can == CAN2)
    {
        RCC_APB1PeriphClockCmd(CAN2_CLK, ENABLE);
    }
	
	/* 时间触发禁止, 时间触发：
	CAN硬件的内部定时器被激活，并且被用于产生时间戳 */
	CAN_InitStructure.CAN_TTCM = DISABLE; 
	/* 自动离线禁止，自动离线：一旦硬件监控到128次11个隐性位，
	就自动退出离线状态。在这里要软件设定后才能退出 */
	CAN_InitStructure.CAN_ABOM = DISABLE; 
	/* 自动唤醒禁止，有报文来的时候自动退出休眠	*/
	CAN_InitStructure.CAN_AWUM = DISABLE; 
 	/* 报文重传, 如果错误一直传到成功止，否则只传一次 */
	CAN_InitStructure.CAN_NART = ENABLE; 
 	/* 接收FIFO锁定, 1--锁定后接收到新的报文摘不要，0--接收到新的报文则覆盖前一报文	*/
	CAN_InitStructure.CAN_RFLM = DISABLE;
	/* 发送优先级  0---由标识符决定  1---由发送请求顺序决定	*/
	CAN_InitStructure.CAN_TXFP = ENABLE;  
	/* 模式*/
	CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; 
	
	/* 波特率设置  分频为2时为1M	  4--500K */
	switch(baudrate)
	{
	case 1000000:
		CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
		CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
		CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
		CAN_InitStructure.CAN_Prescaler = 2;			  	
	  break;
	case 500000:					   	/* 500Kbps */
		CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
		CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
		CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
		CAN_InitStructure.CAN_Prescaler = 4;			
		break;
	case 250000:					  	/* 250Kbps */
		CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
		CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
		CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
		CAN_InitStructure.CAN_Prescaler = 8;			
		break;
	case 125000:					   	/* 125Kbps */		
		CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
		CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
		CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
		CAN_InitStructure.CAN_Prescaler = 16;			  	
		break;
	default:
		break;
	}
	CAN_Init(can, &CAN_InitStructure);
}

void can_it_config(CAN_TypeDef* can, uint8_t preept, uint8_t sub)
{
	NVIC_InitTypeDef NVIC_InitStructure;	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);  
    
    if(can == CAN1)
    {
        NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
    }
    else if(can == CAN2)
    {
        NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;
    }
	
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = preept;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = sub;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	CAN_ITConfig(can, CAN_IT_FMP0, ENABLE);   	
}

// only the canid equal to can_filter_id can be recieved
void can_filter_config(CAN_TypeDef* can, uint32_t can_id)
{
	CAN_FilterInitTypeDef CAN_FilterInitStructure;
	uint32_t id = can_id; 
	uint32_t CAN_FilterNumber = 0;

	//0x7FF 0x1FFFFFFF	-----11位标准ID和29位扩展ID
	//有效位只有29位		
	id &= 0x1FFFFFFF;
	// ID 11bit << 5=16 对其
	id <<= 5;
	//指定了待初始化的过滤器，它的范围是 0到 13。
	if(can == CAN2)
	{
		CAN_FilterInitStructure.CAN_FilterNumber = CAN_FilterNumber+14; 
	}
	else
	{
		CAN_FilterInitStructure.CAN_FilterNumber = CAN_FilterNumber;     
	}

	CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdList;
	CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;

	CAN_FilterInitStructure.CAN_FilterIdHigh = id;
	CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
	// mask 1:must equal to filterId 
	// mask 0:1/0 both OK
	CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFE0;
	CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
	CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
	CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
	CAN_FilterInit(&CAN_FilterInitStructure);        
}

void can_hardware_init(CAN_TypeDef* can, 
	uint32_t baudrate, 
	uint32_t filter_id, 
	uint32_t preept, 
	uint32_t sub)
{
	can_gpio_config(can);
	can_baudrate_set(can, baudrate);
	can_filter_config(can, filter_id);
	can_it_config(can, preept, sub);
}

int test222()
{
    CanTxMsg TxMessage;
	TxMessage.StdId = 7;
	TxMessage.ExtId = 0x01;
	TxMessage.RTR = CAN_RTR_DATA;
	TxMessage.IDE = CAN_ID_STD;
	TxMessage.DLC = 2;
	TxMessage.Data[0]= 1;            
	TxMessage.Data[1]= 1;     
	can_hardware_init(CAN1,1000000,4,1,1);	
    can_hardware_init(CAN2,250000,1,1,1);	
		
    while(1)
    {
        CAN_Transmit(CAN1,&TxMessage);	
    }
    	
   
}

